#pragma once
#ifndef MATERIAL__CREATE_SHADER_DLG_HH__
#define MATERIAL__CREATE_SHADER_DLG_HH__

#include "ui_CreateShaderDialog.h"
#include <LitEditorPrerequisites.h>
#include <LitNameModifier.h>
#include <qhostinfo.h>

namespace Lit
{
	namespace Editor
	{
		namespace Material
		{
			struct ShaderDef
			{
				ShaderDef();
				ShaderDef( const std::string &nam, const std::string &lang, const std::string &prof, const std::string &entry_point );
				ShaderDef( const ShaderDef& def );
				virtual ~ShaderDef();

				std::string name;
				std::string language;
				std::string profile;
				std::string entryPoint;
			};

			struct HeaderDef
			{
				std::string author;
				std::string date;
				std::string version;
				std::string typeDesc;
				std::string typeName;

				HeaderDef( );
				HeaderDef( const HeaderDef& def );
				HeaderDef& operator=( const HeaderDef& def );

				std::string generate() const;
			};
			struct ProgramDef
			{
				ProgramDef( bool accept_=false, const std::string &shaderNam="", const std::string &nam="", bool has_definition = true, bool has_vertex = false, const ShaderDef& vertex = ShaderDef(), bool has_pixel = false, const ShaderDef& pixel = ShaderDef() );
				ProgramDef( const ProgramDef& def );
				virtual ~ProgramDef();

				std::string generate() const;
				
				std::string generateVertex() const;
				std::string generatePixel() const;

				HeaderDef headers;
				ShaderDef vertexShader;
				ShaderDef pixelShader;

				bool hasVertex;
				bool hasPixel;
				bool hasDefinition;

				bool accepted;
				std::string name;
				std::string shaderName;
			};
			class CreateShaderDialog : public QDialog
			{
				Q_OBJECT
			protected:
				Ui::CreateShaderClass	ui;
				unsigned int			mOptions;
				NameModifier			mVertexNamer, 
										mPixelNamer,
										mProgramNamer;
			public:
				enum DialogOption
				{
					NoOption = 0,
					VertexShader = 1<<1,
					PixelShader = 1<<2,
					ProgramDefinition = 1<<3,
					AllOptions = VertexShader|PixelShader|ProgramDefinition
				};
				CreateShaderDialog( 
					QWidget * parent=NULL, 
					const std::string &default_shader_name = "New Shader", 
					unsigned int options = AllOptions,
					const std::string &vertex_prefix="",
					const std::string &vertex_suffix="vert",
					const std::string &pixel_prefix="",
					const std::string &pixel_suffix="frag" 
				);
				~CreateShaderDialog();
				
				const NameModifier& getVertexNamer() const{ return mVertexNamer; }
				const NameModifier& getPixelNamer() const{ return mPixelNamer; }
				const NameModifier& getProgramNamer() const{ return mProgramNamer; }

				NameModifier& getVertexNamer(){ return mVertexNamer; }
				NameModifier& getPixelNamer(){ return mPixelNamer; }
				NameModifier& getProgramNamer(){ return mProgramNamer; }
				
				bool hasProgram() const;
				bool hasFrag() const;
				bool hasVert() const;
				
				std::string vertProfile() const;
				std::string fragProfile() const;
				
				std::string vertEntryPoint() const;
				std::string fragEntryPoint() const;
				
				std::string vertLanguage() const;
				std::string fragLanguage() const;

				std::string progName() const;
				std::string vertName() const;
				std::string fragName() const;

				ProgramDef exec();

				static ProgramDef createShader( QWidget * parent=NULL, const std::string &shaderName="", unsigned int options = AllOptions, const std::string &vertex_prefix="", const std::string &vertex_suffix="vert", const std::string &pixel_prefix="", const std::string &pixel_suffix="frag" );

				unsigned int getOptions() const;
				void setOptions( unsigned int opt );
				void addOption( DialogOption opt );
				bool hasOption( DialogOption opt ) const;
				bool hasOptions( unsigned int opt ) const;

			protected slots:
				void shaderNameChanged(const QString& to);
			};
		};
	};
};

#endif